package org.kleathome.dcpu16;

import java.util.Formatter;
import java.util.Locale;

import org.kleathome.dcpu16.emulator.Emulator;

public class DCPU16Extended extends DCPU16Instruction {

	private char _opcode;
	
	@Override
	public String parseInstruction(String in)
	{
		_opcode = 0x01;
		return super.parseInstruction(in.substring(4).trim());
	}

	@Override
	public void setA(char value)
	{
		if (value != 0x0001)
		{
			System.err.println("Unknown nonbasic Opcode " + Integer.toHexString(value));
			System.exit(2);
		}
		_opcode = value;
	}

	@Override
	public void setB(char value)
	{
		valueA = new DCPU16Literal(value);
	}
	
	@Override
	public int getCycleCost()
	{
		return 2 + super.getCycleCost();
	}

	@Override
	public int getOpCode()
	{
		return 0x00;
	}

	@Override
	public void execute()
	{
		if (_opcode == 0x0001)
		{
			Emulator.push();
			Emulator.setRegister(Emulator.Registers.PC, valueA.getValue());
		}
	}
	
	@Override
	public String getOpCodeLiteral()
	{
		return "JSR";
	}

	@Override
	public DCPU16Instruction getNewObject()
	{
		return new DCPU16Extended();
	}

	@Override
	public String getASCIICode()
	{
		char[] instruction = new char[getInstructionWords()];
		StringBuilder sb = new StringBuilder();
		Formatter formatter = new Formatter(sb, Locale.ENGLISH);

		instruction[0] = 0;
		instruction[0] |= _opcode << 4;
		instruction[0] |= valueA.getOpCode() << 10;
		
		formatter.format("%04x", (int)instruction[0]);

		if (valueA != null && valueA.getInstructionWords() > 0)
		{
			instruction[1] = valueA.getDataCode();
			formatter.format("%04x", (int)instruction[1]);
		}
		return sb.toString();
	}
}
